#include <tls.h>

using namespace std;
using namespace boost::asio;

int main() {
   default_random_engine re {10};

   io_context io;
	ip::tcp::acceptor acceptor(io, ip::tcp::endpoint(ip::tcp::v4(), 4321));
   ip::tcp::iostream tcp_stream;
   acceptor.accept(*tcp_stream.rdbuf()); //打开连接服务器的TCP Stream
   cout << "Server open socket" << endl;

   Hello client_hello_instance;
   parse_clienthello(client_hello_instance, tcp_stream); // 解析client_hello包
   cout << "Server get client hello" << endl;
   unsigned char client_hello_rand[32];
   for (int i = 31;i >= 0; --i){
      client_hello_rand[i] = client_hello_instance.random[i]; // 保存client_hello随机数
   }

   Hello server_hello_instance;
   server_hello_instance.cipher_suites.push_back(0x01);
   server_hello_instance.cipher_suites.push_back(0x13);
   unsigned char server_hello_rand[32];
   for (int i = 31;i >= 0; --i){
      server_hello_instance.random[i] = re();
      server_hello_rand[i] = server_hello_instance.random[i];
   } // 产生随机数
   std::vector<unsigned char> wrapped_hello = wrap_hello(server_hello_instance); // 产生server_hello的TCP包
   for (int i = wrapped_hello.size() - 1;i >= 0; --i){
      tcp_stream << (char)wrapped_hello[i]; // 向流中写入server_hello包
   }
   cout << "Server send server hello" << endl;

   CertificateEntry ser_x509;
   fstream data_in;
   data_in.open("./Server/ca.crt", ios::in);
   string data;
   string buf;
   while (getline(data_in, buf))
   {
      buf += "\n";
      data.append(buf);
   } // 读取证书
   ser_x509.cert_data.assign(data.begin(), data.end());
   ser_x509.certificate_type = CertificateType::X509;
   Certificate ser_cert_instance;
   ser_cert_instance.certificate_list.push_back(ser_x509);
   std::vector<unsigned char> wrapped_cert = wrap_certificate(ser_cert_instance);
   for (int i = wrapped_cert.size() - 1;i >= 0; --i){
      tcp_stream << (char)wrapped_cert[i]; // 写入证书
   }
   data_in.close();
   cout << "Server send certificate" << endl;

   Certificate cli_cert_instance;
   parse_certificate(cli_cert_instance, tcp_stream);// 解析client_的x509包
   CertificateEntry cli_cert_x509_instance = cli_cert_instance.certificate_list[0];
   fstream data_out;
   data_out.open("/tmp/cli_crt.pem", ios::out);
   for (int i = cli_cert_x509_instance.cert_data.size() - 1;i >= 0 ; --i){
      data_out << (char)cli_cert_x509_instance.cert_data[i];
   }
   data_out.close();
   auto cli_botan_x509_instance = Botan::X509_Certificate("/tmp/cli_crt.pem"); // 解析证书
   cout << "Server get certificate" << endl;
   string x509_string = cli_botan_x509_instance.to_string();
   cout << x509_string;

   KeyShareEntry key_instance;
   parse_keyshare(key_instance, tcp_stream); // 读取key_exchange包
   // for (int i = 0;i < key_instance.key_exchange.size(); ++i){
   //    cout << (unsigned short)key_instance.key_exchange[i] << " ";
   // }
   Botan::AutoSeeded_RNG rng;
   data_in.open("./Server/ca.crt", ios::in);
   Botan::DataSource_Stream key_in("./Server/pkcs8.pem"); // 读取私钥
   data_in.close();
   std::unique_ptr<Botan::Private_Key> ser_x509_privatekey{ Botan::PKCS8::load_key(key_in) };
   Botan::PK_Decryptor_EME dec(*ser_x509_privatekey, rng, "EME-PKCS1-v1_5");
   Botan::SecureVector<Botan::byte> sec_key = dec.decrypt(key_instance.key_exchange); // 用私钥解密Client的随机数
   vector<uint8_t> key;
   vector<uint8_t> iv;
   key.resize(16);
   iv.resize(16);
   for (int i = 0;i < 16; ++i){
      key[i] = sec_key[i];
      iv[i]  = sec_key[i + 16];
   }
   cout << "Server get keyshare" << endl;

   Payload payload_instance;
   parse_payload(payload_instance, tcp_stream);
   vector<uint8_t> block = payload_instance.payload;
   const auto aes_enc = Botan::Cipher_Mode::create_or_throw("AES-128/CBC/PKCS7", Botan::Cipher_Dir::Decryption);
   aes_enc->set_key(key);
   // Botan::secure_vector<uint8_t> iv = rng.random_vec(aes_enc->default_nonce_length());
   aes_enc->start(iv);
   aes_enc->finish(block);// 用AES解密文本
   string string_out((const char*)block.data(), block.size());
	cout<< string_out <<endl;
}
